package com.mytrans.transaction;


import com.mytrans.beans.TranceRecordBean;
import com.mytrans.client.MytransServerClient;
import com.mytrans.util.JsonType;
import com.zhou.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

public abstract class AbstractTransactionExecutor<T> implements TransactionExecutor<T>{

    @Autowired
    protected MytransServerClient myTransServerClient;
    @Autowired
    protected TokenManager tokenManager;

    public String serverName;

    /**
     * 需要执行的预扣款任务
     * @param t
     */
    @Override
    public abstract void task(T t);

    /**
     * 执行的回滚任务
     * @param t
     */
    @Override
    public abstract void rollBack(T t);

    /**
     * 执行的提交任务
     * @param t
     */
    @Override
    public abstract void commit(T t);

    /**
     * 获取任务key
     */
    @Override
    public abstract String getKey();

    /**
     * 获取参数的类型
     */
    @Override
    public abstract JsonType<T> getParamType();

    /**
     * 真正执行事务预扣使用
     * @param t
     */
    @Override
    @Transactional
    public void excuteTask(T t) throws IOException {
        this.task(t);
        myTransServerClient.taskSuccess(createTranceRecord(t));

    }

    /**
     * 真正执行的预扣款任务
     * @param t
     */
    @Override
    @Transactional
    public void excuteRollBack(T t, String token) throws IOException {
        this.rollBack(t);
        myTransServerClient.rollBackSuccess(createTranceRecord(t, token));
    }

    /**
     * 真正执行的预扣款任务
     * @param t
     */
    @Override
    @Transactional
    public void excuteCommit(T t, String token) throws IOException {
        this.commit(t);
        myTransServerClient.commitSuccess(createTranceRecord(t, token));
    }

    private TranceRecordBean createTranceRecord(T t){
        return createTranceRecord(t, tokenManager.getLocalToken());
    }

    private TranceRecordBean createTranceRecord(T t, String token){
        TranceRecordBean bean = new TranceRecordBean();
        long currentTime = System.currentTimeMillis();
        bean.setCreateTime(currentTime);
        bean.setModifyTime(currentTime);
        bean.setData(JsonUtil.getGson().toJson(t));
        bean.setExecutorKey(getKey());
        bean.setToken(token);
        bean.setServerName(this.serverName);
        return bean;
    }
}
